#pragma once

#include "Stdafx.h"
#include "BVHHandle.h"

#include "Lux\point.h"
#include "Lux\triangle.h"
#include "Lux\qbvhaccel.h"


namespace DLLx {

	using namespace System::Collections::Generic;

	[Serializable()]
	public value struct QBVHAccelNode {
		inline_array<float,10> bbox;
		inline_array<unsigned int,4> children;
	};

	union  M128F {
		__m128 v;    // SSE 4 x float vector
		float a[4];  // scalar array of 4 floats
	} U;

	/*
	static float vectorGetByIndex(__m128 V, unsigned int i)
	{
		U u;
		u.v = V;
		return u.a[i];
	};*/

	public ref class QBVHHandle : public IDisposable
	{
	public:

		QBVHHandle(TriangleData^ data)
		{
			const int maxPrimsPerLeaf = 4;
			const int fullSweepThreshold = 4 * maxPrimsPerLeaf;
			const int skipFactor = 1;
			accel = new QBVHAccel(data->nVert,data->nTri, data->triangles, data->points,maxPrimsPerLeaf, fullSweepThreshold, skipFactor); 
		}

		List<QBVHAccelNode>^ GetData()
		{
			List<QBVHAccelNode>^ list = gcnew List<QBVHAccelNode>(accel->nNodes);
			for(unsigned int i=0;i<accel->nNodes;i++) {
				//QBVHNode node = accel->nodes[i];
				QBVHAccelNode resNode = QBVHAccelNode();
				resNode.bbox = inline_array<float,10>();
//				resNode.bbox = accel->nodes[i].bboxes;
				resNode.children = inline_array<unsigned int, 4>();
				/*
				node.bboxes


					primitive = node.primitive;
				resNode->skipIndex = node.skipIndex;
				resNode->bbox =gcnew Box(gcnew VertInfo(node.bbox.pMin.x, node.bbox.pMin.y, node.bbox.pMin.z),
										 gcnew VertInfo(node.bbox.pMax.x, node.bbox.pMax.y, node.bbox.pMax.z));
										 */
				list->Add(resNode);
			}
			return list;
		};


		

		~QBVHHandle()
		{
			this->!QBVHHandle();
		}

		!QBVHHandle()
		{
			delete accel;
		}

	private:
		QBVHAccel* accel;
	};
}

